<?php

App::uses('CustomDataModel', 'Base.Model');

class SourceDocumentTag extends CustomDataModel {

    public $actsAs = array(
        'Base.CommonValidation'
    );
    public $recursive = -1;
    public $validate = array(
        'source_document_id' => array(
            'foreignKey' => array(
                'rule' => array('foreignKey'),
            ),
            'isUniqueInContext' => array(
                'rule' => array('isUniqueInContext', 'tag_id'),
            ),
        ),
        'tag_id' => array(
            'foreignKey' => array(
                'rule' => array('foreignKey'),
            ),
            'isUniqueInContext' => array(
                'rule' => array('isUniqueInContext', 'source_document_id'),
            ),
        ),
    );
    public $belongsTo = array(
        'Tag',
        'SourceDocument',
    );

    protected function customData() {

        $data = array();

        $tags = $this->Tag->find('all');

        $sourceDocumentTags = array();
        
        $RawFileTag = ClassRegistry::init('RawFileTag');

        foreach ($tags as $tag) {
            $rawFileTags = $RawFileTag->findAllByTagId($tag['Tag']['id']);
            $sourceDocumentTags = array();
            foreach ($rawFileTags as $rawFileTag) {
                $sourceDocumentName = $this->SourceDocument->buildNameFromFileName(
                        ModelTraverser::value($RawFileTag, $rawFileTag, 'RawFile.name')
                );
                $sourceDocument = $this->SourceDocument->findByName($sourceDocumentName);
                if (!empty($sourceDocument)) {
                    $sourceDocumentTags[$sourceDocument['SourceDocument']['id']] = true;
                }                
            }

            foreach (array_keys($sourceDocumentTags) as $sourceDocumentId) {
                $data[] = array(                    
                    'source_document_id' => $sourceDocumentId,
                    'tag_id' => $tag['Tag']['id'],
                    'complete' => $this->isComplete($sourceDocumentName, $tag['Tag']['id']),
                );
            }
        }



        return $data;
    }

    private function isComplete($sourceDocumentId, $tagId) {
        foreach (
        $this->SourceDocument->RawFile->findAllBySourceDocumentId($sourceDocumentId)
        as $rawFile
        ) {
            $rawFileTag = $this->RawFileTag->find(
                    'first'
                    , array(
                'conditions' => array(
                    "RawFileTag.tag_id" => $tagId,
                    "RawFileTag.raw_file_id" => $rawFile['RawFile']['id'],
                )
                    )
            );            
            if (!$rawFileTag) {
                return false;
            }
        }

        return true;
    }

    public function complete($sourceDocumentTag) {
        return $this->completeBySourceDocumentAndTag(
                        $sourceDocumentTag[$this->alias]['source_document_id']
                        , $sourceDocumentTag[$this->alias]['tag_id']
        );
    }

    private function completeBySourceDocumentAndTag($sourceDocumentId, $tagId) {
        $RawFileTag = ClassRegistry::init('RawFileTag');
        foreach (
        $this->SourceDocument->RawFile->findAllBySourceDocumentId($sourceDocumentId)
        as $rawFile
        ) {
            $rawFileTag = $RawFileTag->find(
                    'first'
                    , array(
                'conditions' => array(
                    "RawFileTag.tag_id" => $tagId,
                    "RawFileTag.raw_file_id" => $rawFile['RawFile']['id'],
                )
                    )
            );            

            if (!$rawFileTag) {
                $RawFileTag->create();
                $rawFileTag[$RawFileTag->alias] = array(
                    'tag_id' => $tagId,
                    'raw_file_id' => $rawFile['RawFile']['id'],
                );
                Basics::saveModelOrThrowException($RawFileTag, $rawFileTag);
            }
        }
    }

    protected function customSave($oldData, $newData) {
        if (empty($oldData)) {
            return $this->completeBySourceDocumentAndTag(
                            $this->data[$this->alias]['source_document_id']
                            , $this->data[$this->alias]['tag_id']
            );
        } else {
            throw new Exception("Update SourceDocumentTag is not supported");
        }
    }

    protected function customDelete($row) {
        $RawFileTag = ClassRegistry::init('RawFileTag');
        foreach (
        $this->SourceDocument->RawFile->findAllBySourceDocumentId($row['source_document_id'])
        as $rawFile
        ) {
            $rawFileTag = $RawFileTag->find(
                    'first'
                    , array(
                'conditions' => array(
                    "RawFileTag.tag_id" => $row['tag_id'],
                    "RawFileTag.raw_file_id" => $rawFile['RawFile']['id'],
                )
                    )
            );
            Basics::deleteModelOrThrowException($RawFileTag, $rawFileTag);
        }
    }

    public function absolutePath($rowFileTag) {
        return $this->Tag->absolutePath(array($this->Tag->alias => $rowFileTag[$this->Tag->alias]))
                . DIRECTORY_SEPARATOR . $rowFileTag[$this->alias]['name'];
    }

    public function findBySourceDocumentAndTag($sourceDocumentId, $tagId) {
        return $this->find(
                        'first', array(
                    'conditions' => array(
                        "{$this->alias}.source_document_id" => $sourceDocumentId,
                        "{$this->alias}.tag_id" => $tagId,
                    )
                        )
        );
    }

    public function setEnabled($sourceDocumentId, $tagId, $enabled) {
        $sourceDocumentTag = $this->findBySourceDocumentAndTag($sourceDocumentId, $tagId);

        if ($enabled && !$sourceDocumentTag) {
            $sourceDocumentTag[$this->alias] = array(
                'source_document_id' => $sourceDocumentId,
                'tag_id' => $tagId,
            );
            $this->create();
            return $this->save($sourceDocumentTag);
        } else if (!$enabled && $sourceDocumentTag) {
            return $this->delete($sourceDocumentTag[$this->alias]['id']);
        }
        else {
            return true;
        }
    }

}

?>
